package fm.yichenet.mongo.service.impl;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBObject;
import fm.cache.ConfigCache;
import fm.dao.HibernateBaseDao;
import fm.dao.MongoBaseDao;
import fm.dto.AdminUser;
import fm.dto.SystemUser;
import fm.entity.ArticleComment;
import fm.entity.PublicNumber;
import fm.dto.NeiyiUser;
import fm.entityEnum.ArticleAdEnum;
import fm.entityEnum.CollectTypeEnum;
import fm.exception.BizException;
import fm.huanxin.api.MessageApi;
import fm.mongo.MCondition;
import fm.mongo.MRel;
import fm.mongo.MongoTable;
import fm.mongoService.UserService;
import fm.util.CommonUtils;
import fm.util.DateUtils;
import fm.web.CurrentRequest;
import fm.yichenet.dto.ArticleDto;
import fm.yichenet.mongo.service.ArticleService;
import fm.yichenet.service.OrderService;
import org.apache.calcite.avatica.proto.Common;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.sql.Date;
import java.util.*;

/**
 * Created by 宏炜 on 2017-05-26.
 */
@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    MongoBaseDao mongoBaseDao;

    @Autowired
    HibernateBaseDao hibernateBaseDao;

    @Autowired
    OrderService orderService;

    @Autowired
    UserService userService;

    @Override
    public DBObject mergeArticle(ArticleDto articleDto) throws Exception {
        if (CommonUtils.isEmpty(articleDto.getType())) {
            throw new BizException("图文类型不能为空");
        }
        if (CommonUtils.isEmpty(articleDto.getSection_id())) {
            throw new BizException("板块不能为空");
        }

        if (articleDto.getType().equals(1)) {
            if (CommonUtils.isEmpty(articleDto.getPortal_img())) {
                throw new BizException("文章封面不能为空");
            }
            if (CommonUtils.isEmpty(articleDto.getMain_title())) {
                throw new BizException("文章标题不能为空");
            }
            if (CommonUtils.isEmpty(articleDto.getSub_title())) {
                throw new BizException("文章副标题不能为空");
            }
        }
        if (CommonUtils.isEmpty(articleDto.getContent())) {
            throw new BizException("内容不能为空");
        }


        if (CommonUtils.isEmpty(articleDto.getId())) {
            articleDto.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            articleDto.setCreate_time(new Date(System.currentTimeMillis()));
            articleDto.setIs_top(0);
            Object user = CurrentRequest.getCurrentLoginUser();
            if (user instanceof NeiyiUser) {
                articleDto.setUser_nickname(CommonUtils.isEmpty(((NeiyiUser) user).getCompanyName()) ? "" : ((NeiyiUser) user).getCompanyName());
                articleDto.setUser_head_img_url(CommonUtils.isEmpty(((NeiyiUser) user).getUserLogo()) ? "" : ((NeiyiUser) user).getUserLogo());
                articleDto.setUser_id((String) ((NeiyiUser) user).getId());
                articleDto.setUser_contact(((NeiyiUser) user).getUserContact());
            }
            else if (user instanceof AdminUser) {
                articleDto.setUser_nickname(((AdminUser) user).getName());
                articleDto.setUser_head_img_url(CommonUtils.isEmpty(ConfigCache.getConfig("DEFAULT_LOGO")) ? "" : ConfigCache.getConfig("DEFAULT_LOGO"));
                articleDto.setUser_id((String) new AdminUser().getId());
            } else {
                throw new BizException("无法获取当前用户信息,发布失败");
            }
            mongoBaseDao.insert(articleDto.toDBObject(), MongoTable.community_article);
            return articleDto.toDBObject();
        } else {
            Map<String, Object> query = new HashedMap();
            query.put("id", articleDto.getId());
            DBObject dbObject = (DBObject) mongoBaseDao.findOne(query, DBObject.class, MongoTable.community_article);
            if (CommonUtils.isEmpty(dbObject)) {
                throw new BizException("所修改的内容不存在");
            }
            dbObject.put("content", articleDto.getContent());
            dbObject.put("pics", articleDto.getPics());
            dbObject.put("portal_img", articleDto.getPortal_img());
            dbObject.put("main_title", articleDto.getMain_title());
            dbObject.put("sub_title", articleDto.getSub_title());
            dbObject.put("section_id", articleDto.getSection_id());
            mongoBaseDao.updateOne(query, dbObject.toMap(), MongoTable.community_article);
            return articleDto.toDBObject();
        }
    }

    @Override
    public void addFlag(String id, ArticleAdEnum newFlag, String startTime, String endTime) throws Exception {
        DBObject article = getArticleInfo(id);
        DBObject flags = (DBObject) article.get("ad_option");
        if (!CommonUtils.isEmpty(flags) && flags.containsField(newFlag.toString())) {
            DBObject flag = (DBObject) flags.get(newFlag.toString());

            java.util.Date endTime1 = (java.util.Date) flag.get("end_time");
            endTime1 = new java.util.Date(endTime1.getTime() + DateUtils.getTimeBetween(DateUtils.parseDate(startTime), DateUtils.parseDate(endTime)));
            flag.put("end_time", endTime1);
        } else {
            if(CommonUtils.isEmpty(flags)){
                flags = new BasicDBObject();
            }
            DBObject flag = new BasicDBObject();
            flag.put("start_time", new java.util.Date());
            flag.put("end_time", DateUtils.parseDate(endTime));
            flags.put(newFlag.toString(), flag);
        }
        updateArticle(id, new BasicDBObject("ad_option", flags));
    }


    @Override
    public void removeFlag(String id, ArticleAdEnum flag) throws Exception {
        Map<String, Object> query = new HashedMap();
        query.put("id", id);
        DBObject dbObject = (DBObject) mongoBaseDao.findOne(query, DBObject.class, MongoTable.community_article);
        if (CommonUtils.isEmpty(dbObject)) {
            throw new BizException("取消置顶的内容不存在");
        }
        DBObject flags = (DBObject) dbObject.get("ad_option");
        if (!CommonUtils.isEmpty(flags) && flags.containsField(flag.toString())) {
            flags.removeField(flag.toString());
            mongoBaseDao.updateOne(query, new BasicDBObject("ad_option", flags), MongoTable.community_article);

        }
    }

    @Override
    public List getArticleForPage(Map params, Integer pageSize, Integer pageNum) throws Exception {
        DBObject sort = new BasicDBObject("create_time", Sort.Direction.DESC.toString());
//        sort.put("is_top", Sort.Direction.DESC.toString());
        if (pageNum != null && pageSize != null) {
            return (List<DBObject>) mongoBaseDao.getPageList(params, DBObject.class, pageSize, pageNum, MongoTable.community_article, sort);
        } else {
            return (List<DBObject>) mongoBaseDao.getList(params, DBObject.class, MongoTable.community_article, sort);
        }
    }

    @Override
    public long countArticles(Map params) throws Exception {
        return mongoBaseDao.count(params, MongoTable.community_article);
    }

    @Override
    public DBObject commentArticle(ArticleComment articleComment) throws Exception {
        articleComment.setComment_time(new Date(System.currentTimeMillis()));
        if (CommonUtils.isEmpty(articleComment.getType())) {
            throw new BizException("类型不能为空");
        }

        if (articleComment.getType().equals(1)) {


            if (CommonUtils.isEmpty(articleComment.getContent())) {
                throw new BizException("评论内容不能为空");
            }
            if (!CommonUtils.isEmpty(articleComment.getTo_user_id())) {
                if(articleComment.getTo_user_id().equals(articleComment.getUser_id())){
                    throw new BizException("无法回复自己!");
                }
                if (!articleComment.getTo_user_id().equals("0")) {
                    NeiyiUser toUser = userService.getById(articleComment.getTo_user_id());
                    if (CommonUtils.isEmpty(toUser)) {
                        throw new BizException("评论对象不存在");
                    }
                    articleComment.setTo_user_nickname(toUser.getName());
                    articleComment.setTo_user_head_img_url(toUser.getUserLogo());
                } else {
                    articleComment.setTo_user_nickname(new AdminUser().getName());
                    articleComment.setTo_user_head_img_url(CommonUtils.isEmpty(ConfigCache.getConfig("DEFAULT_LOGO")) ? "" : ConfigCache.getConfig("DEFAULT_LOGO"));
                }

            }
        }

        Map<String, Object> query = new HashedMap();
        query.put("id", articleComment.getArticle_id());

        DBObject article = (DBObject) mongoBaseDao.findOne(query, DBObject.class, MongoTable.community_article);
        if (!articleComment.getType().equals(1)) {
            if (CurrentRequest.isAdmin()){
                SystemUser user =(SystemUser)CurrentRequest.getCurrentLoginUser();
                if (article.get("user_id").toString().equals(user.getId())) {
                    throw new BizException("无法给自己点赞");
                }
            }
            NeiyiUser user = (NeiyiUser) CurrentRequest.getCurrentLoginUser();
            if (article.get("user_id").toString().equals(user.getId())) {
                throw new BizException("无法给自己点赞");
            }
            Map<String, Object> queryComment = new HashedMap();
            queryComment.put("article_id", articleComment.getArticle_id());
            queryComment.put("user_id", articleComment.getUser_id());
            queryComment.put("type", 0);
            long selLikesCount = mongoBaseDao.count(queryComment, MongoTable.article_comment);
            if (selLikesCount > 0) {
                throw new BizException("该条文章或图文已经点赞");
            }
        }
//        if (!CommonUtils.isEmpty(articleComment.getTo_user_id())) {
//            if (articleComment.getTo_user_id() != "-1") {
//                MessageApi.sendForumMsg("有新的社区动态#" + articleComment.getArticle_id() + "#", "wx_" + article.get("uuid"));
//            }
//        }

//        List<DBObject> comments = (List<DBObject>) (CommonUtils.isEmpty(article.get("comments")) ? new ArrayList<DBObject>() : article.get("comments"));
//        List<DBObject> likes = (List<DBObject>) (CommonUtils.isEmpty(article.get("likes")) ? new ArrayList<DBObject>() : article.get("likes"));

        if (articleComment.getType().equals(1)) {
                article.put("comments_count", article.get("comments_count")==null? 1:(Long)article.get("comments_count")+1);
        } else {
                article.put("likes_count", article.get("likes_count")==null? 1:(Long)article.get("likes_count")+1);
            }


        mongoBaseDao.updateOne(query, article.toMap(), MongoTable.community_article);

        mongoBaseDao.insert(articleComment.toDBObject(), MongoTable.article_comment);
        return articleComment.toDBObject();
    }

    @Override
    public List getCommentsList(Integer pageSize, Integer pageNum, String article_id, Integer type) throws Exception {
        Map<String, Object> query = new HashedMap();
        query.put("article_id", article_id);
        query.put("type", type);
        return (List<DBObject>) mongoBaseDao.getPageList(query, DBObject.class, pageSize, pageNum, MongoTable.article_comment);
    }

    @Override
    public long countComments(String article_id, Integer type) throws Exception {
        Map<String, Object> query = new HashedMap();
        query.put("article_id", article_id);
        query.put("type", type);
        return mongoBaseDao.count(query, MongoTable.article_comment);
    }

    @Override
    public DBObject getArticleInfo(String article_id) throws Exception {
        Map<String, Object> query = new HashedMap();
        query.put("id", article_id);
        DBObject article = (DBObject) mongoBaseDao.findOne(query, DBObject.class, MongoTable.community_article);
        if (article == null) {
            throw new BizException("未找到相关的文章信息!");
        }
        Long comments_count = countComments(article_id, 1);
        Long likes_count = countComments(article_id, 0);
        article.put("comments_count", comments_count == null ? 0 : comments_count);
        article.put("likes_count", likes_count == null ? 0 : likes_count);

//        article.removeField("likes");
//        article.removeField("comments");
        article.removeField("_id");
        return article;
    }

    @Override
    public void deleteArticle(String article_id) throws Exception {
        Map<String, Object> query = new HashedMap();
        query.put("id", article_id);
        mongoBaseDao.delete(query, MongoTable.community_article);
    }

    @Override
    public void updateArticle(String articleId, DBObject article) {
        MCondition mc = MCondition.create(MRel.and);
        mc.append("id", articleId);

        mongoBaseDao.updateOne(mc.toDBObject().toMap(), article.toMap(), MongoTable.community_article);
    }

    @Override
    public long countInfoArticle(Map param) {
        long count = mongoBaseDao.count(param, MongoTable.portal_article);
        return count;
    }

    @Override
    public List<DBObject> getInfoArticleList(DBObject query) throws Exception {
        List<DBObject> infos = (List<DBObject>) mongoBaseDao.getList(query.toMap(), DBObject.class, MongoTable.community_article);
        return infos;
    }

    @Override
    public List<DBObject> getInfoArticleListByparam(Map params) throws Exception {
        List<DBObject> infos = (List<DBObject>) mongoBaseDao.getList(params, DBObject.class, MongoTable.community_article, new BasicDBObject("create_time", Sort.Direction.DESC.toString()));
        return infos;
    }

    @Override
    public void addInfoArticle(DBObject info) throws Exception {
        mongoBaseDao.insert(info, MongoTable.portal_article);
    }

    @Override
    public void deleteInfoArticle(DBObject query) {
        mongoBaseDao.delete(query.toMap(), MongoTable.portal_article);
    }

    @Override
    public void deleteUserArticle(NeiyiUser user, String articleId) {
        Map<String, Object> query = new HashedMap();
        query.put("uuid", user.getId());
        query.put("id", articleId);
        mongoBaseDao.delete(query, MongoTable.community_article);
    }

    @Override
    public void articleCollect(String article_id,boolean flag) throws Exception{
        Map param = new HashMap();
        if ( CurrentRequest.getCurrentLoginUser()==null){
            throw new BizException("请先登录!");
        }
        Map<String, Object> query = new HashedMap();
        query.put("id", article_id);
        DBObject article = (DBObject) mongoBaseDao.findOne(query, DBObject.class, MongoTable.community_article);
        if(article==null){
            throw new BizException("对应文章不存在!");
        }
        if(CurrentRequest.isAdmin()){
            SystemUser user = (SystemUser) CurrentRequest.getCurrentLoginUser();
            param.put("user_id",user.getId());
        }
        else{
            NeiyiUser user = (NeiyiUser) CurrentRequest.getCurrentLoginUser();
            param.put("user_id",user.getId());
        }
        param.put("type", CollectTypeEnum.ARTICLE);
        param.put("id",article_id);
        param.put("head_img",article.get("portal_img"));
        param.put("name",article.get("main_title"));
       DBObject collect = (DBObject) mongoBaseDao.findOne(param,DBObject.class,MongoTable.collection);
       if (collect==null&&flag){
           mongoBaseDao.insert(param,MongoTable.collection);
           article.put("collect_count",article.get("collect_count") == null ? 1 : (Long)article.get("collect_count")+1);
           mongoBaseDao.updateOne(query, article.toMap(), MongoTable.community_article);
       }
       else if(collect!=null&&!flag){
           mongoBaseDao.delete(param,MongoTable.collection);
           article.put("collect_count",article.get("collect_count") == null ? 0 : (Long)article.get("collect_count")-1);
           mongoBaseDao.updateOne(query, article.toMap(), MongoTable.community_article);
       }
    }

    @Override
    public void commentLike(String id) throws Exception {
        Map query = new HashMap();
        query.put("id",id);
        DBObject comment =(DBObject) mongoBaseDao.findOne(query,DBObject.class,MongoTable.article_comment);
        if(comment==null){
            throw new BizException("未找到对应评论");
        }
        comment.put("like_count",comment.get("like_count")==null? 1:(Long)comment.get("like_count")+1);
        mongoBaseDao.updateOne(query,comment.toMap(),MongoTable.article_comment);
    }
}
